//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __TESTING_ASM_H__
#define __TESTING_ASM_H__

#include <testing/tp_slot.h>

EXTERN_C ECode CDECL SysQueryPerformanceCounter (Int64 *pPerformanceCount, Int64 *pFrequency);

EXTERN_C inline void __cdecl GetCycleCount(TIMESTAMP * pTsp, int bReset = 0)
{
    static Int64 s_uStartValue = 0;
    static Int64 s_uEndValue = 0;
    static Int64 s_uValue = 0;

    if (bReset) {
        SysQueryPerformanceCounter(&s_uStartValue, NULL);
    }
    SysQueryPerformanceCounter(&s_uStartValue, NULL);
    s_uValue = s_uEndValue - s_uStartValue;

    pTsp->high = s_uValue >> 32;
    pTsp->low  = (UInt32)s_uValue;
}

EXTERN_C inline void timepeg_stamp(TIMESTAMP *pstamp, int bReset = 0)
{
    GetCycleCount(pstamp, bReset);
}

// add two timepegs
inline void timepeg_add(TIMESTAMP* padd, TIMESTAMP* pacc)
{
    pacc->high += padd->high;
    pacc->low  += padd->low;
    if (pacc->low < padd->low) {
        pacc->high++;
    }
}

// sub two timepegs
inline void timepeg_sub(TIMESTAMP* psub, TIMESTAMP* pacc)
{
    pacc->low -= psub->low;
}

EXTERN_C void timepeg_asm();

#define TIMEPEG_ASM(_M_name)                    \
    do {                                        \
        ASM("call   _timepeg_asm;");            \
    } while (0);

#endif
